/******************************************************************************

  Copyright (C), 2004-2014, Hisilicon Tech. Co., Ltd.

 ******************************************************************************
  File Name     : isp_pregamma.c
  Version       : Initial Draft
  Author        : Hisilicon multimedia software group
  Created       : 2014/08/19
  Description   : 
  History       :
  1.Date        : 2014/08/19
    Author      : q00214668
    Modification: Created file

******************************************************************************/
#include <math.h>
#include "isp_alg.h"
#include "isp_sensor.h"
#include "isp_config.h"
#include "isp_ext_config.h"
#include "hi_math.h"
#include "isp_math_utils.h"

#ifdef __cplusplus
#if __cplusplus
extern "C"{
#endif
#endif /* End of #ifdef __cplusplus */

#define HI_ISP_GAMMAFE_MIX_CTRL (255)
#define HI_ISP_GAMMAFE_DEFAULT_STATUS (0)
#define HI_ISP_GAMMAFE_BITW_IN        (20)
#define HI_ISP_GAMMAFE_BITW_OUT       (16)
//#define HI_ISP_GAMMAFE_DEFAULT_K      (16)
//#define HI_ISP_GAMMAFE_DEFAULT_S      (14)
#if 0
#ifndef MAX
#define MAX(a, b) (((a) < (b)) ?  (b) : (a))
#endif

#ifndef MIN
#define MIN(a, b) (((a) > (b)) ?  (b) : (a))
#endif
#endif

typedef struct hiISP_GAMMAFE_S
{
    //HI_BOOL bUpGammaFeLut;  
	HI_U16 Gamma_Fe_LUT0[GAMMA_FE0_LUT_SIZE];
	HI_U32 Gamma_Fe_LUT1[GAMMA_FE1_LUT_SIZE];
    //HI_U32 K;
    //HI_U32 S;
	HI_U8  u8GammaFeMixCtrl;
} ISP_GAMMAFE_S;

ISP_GAMMAFE_S g_astGammaFeCtx[ISP_MAX_DEV_NUM] = {{{0}}};
#define GAMMAFE_GET_CTX(dev, pstCtx)   pstCtx = &g_astGammaFeCtx[dev]

static HI_VOID GammaFeExtRegsDefault(HI_VOID)
{
    return;
}

static HI_VOID GammaFeRegsDefault(HI_VOID) 
{
    return;
}

static HI_VOID GammaFeExtRegsInitialize(ISP_DEV IspDev)
{
    return;
}
#if 0
HI_U32 GlobalToneCurve(HI_U32 X, ISP_GAMMAFE_S *pstGammaFe)

{
    HI_S32 K;
    HI_S32 S;  
    HI_DOUBLE YLogScale;
    HI_U32 YLogScaleMix;
    HI_DOUBLE Wgt,Curve;
    HI_U32 Line;
    HI_U32 J;
    HI_DOUBLE Diff;
    HI_DOUBLE T,W1,W2,S1,S2;
    HI_DOUBLE Smooth;
    HI_DOUBLE temp1,temp2;
   
    K = (HI_S32)pstGammaFe->K;
    S =  (HI_S32)pstGammaFe->S; 
  
   
    YLogScale = (1<<(16-K))*pow(X,((HI_DOUBLE)K/20));

    Wgt  = pow(((HI_DOUBLE)((1<<20)-1-X)/((1<<20)-1)),S);

    Curve = (YLogScale*Wgt + ((HI_DOUBLE)X/16)*(1-Wgt));    

    Line = X;

    J = (HI_U32)(pow(2,(HI_DOUBLE)(K-16)*20/(K-20))*(pow(((HI_DOUBLE)(S-8)/6),0.65)*0.05396+0.94604)+0.5)-1;

    Diff = Line - Curve;

    T = (HI_DOUBLE)450/3874*J;

    W1 = (HI_DOUBLE)110*8/3874*J;

    W2 = (HI_DOUBLE)475*8/3874*J;

    S1 = 1.25;

    S2 = 0.7;

    temp1 = MAX(MIN(pow((Diff+W1)/W1,S1)*T,((Diff<0)*T+(Diff>=0)*(1-pow((Diff/W2),S2))*T)),0);

    temp2 = MIN(MAX((((HI_DOUBLE)X - J/5)/J*6),0),1);

    Smooth = temp1*temp2;

    YLogScaleMix =  (HI_U32)(MIN(Curve,Line) - Smooth + 0.5);
   
        
    return YLogScaleMix;

}

HI_S32 GenerateGammaFeLut(ISP_GAMMAFE_S *pstGammaFe)

{
    HI_U32 k = 0;
    HI_U32 i,x,x1,x2;
    HI_U32 Idx_In,Ypt_In;
    HI_U32 Lut0_Out,Lut0_Out1,Lut0_Out2;
    HI_U32 Temp;
    HI_U32 imax,imin;

    for(i=0;i<257;i++)
    {       
		imin = k;
         
         imax = 1048576;
         while(imax >= imin)        
         {

             x = (imin + imax+1)/2;

             x1 = MAX((HI_S32)(x-1),0);

             x2 = MIN(x+1,1048576);
             
             Idx_In = x>>15;
             
             Ypt_In = Idx_In<<15;
             
             Temp = pstGammaFe->Gamma_Fe_LUT0[MIN((Idx_In+1),32)] - pstGammaFe->Gamma_Fe_LUT0[Idx_In];

             Lut0_Out = (Temp*(x-Ypt_In)>>11) + (pstGammaFe->Gamma_Fe_LUT0[Idx_In]<<4);

             Idx_In = x1>>15;

             Ypt_In = Idx_In<<15;

             Temp = pstGammaFe->Gamma_Fe_LUT0[MIN((Idx_In+1),32)] - pstGammaFe->Gamma_Fe_LUT0[Idx_In];

             Lut0_Out1 = (Temp*(x1-Ypt_In)>>11) + (pstGammaFe->Gamma_Fe_LUT0[Idx_In]<<4);

             Idx_In = x2>>15;

             Ypt_In = Idx_In<<15;

             Temp = pstGammaFe->Gamma_Fe_LUT0[MIN((Idx_In+1),32)] - pstGammaFe->Gamma_Fe_LUT0[Idx_In];

             Lut0_Out2 = (Temp*(x2-Ypt_In)>>11) + (pstGammaFe->Gamma_Fe_LUT0[Idx_In]<<4);

             if((Lut0_Out == MIN(i*4096,1048560))||((Lut0_Out1 < MIN(i*4096,1048560))&&(Lut0_Out2 > MIN(i*4096,1048560))))
             {

                //if matched assign inverse function value

                 k = x;
                 
                 pstGammaFe->Gamma_Fe_LUT1[i] = GlobalToneCurve(MIN(k+1,1048575),pstGammaFe);

                 pstGammaFe->Gamma_Fe_LUT1[i] = MIN(pstGammaFe->Gamma_Fe_LUT1[i],65535);

                 break;
             }
             else if(Lut0_Out < MIN(i*4096,1048560))
             {
                imin = x + 1;
             }
             else
             {
                imax = x - 1;
             }
            
         }

         pstGammaFe->Gamma_Fe_LUT1[i] = MIN(pstGammaFe->Gamma_Fe_LUT1[i],65535);
    }
    
    return HI_SUCCESS;

}
#endif
static HI_VOID GammaFeRegsInitialize(ISP_DEV IspDev)
{
    HI_S32 i;
	HI_U8 u8WDRMode;
    ISP_CMOS_DEFAULT_S *pstSnsDft = HI_NULL;
	ISP_GAMMAFE_S *pstGammaFe = HI_NULL;
    ISP_CTX_S *pstIspCtx = HI_NULL;    
    ISP_GET_CTX(IspDev, pstIspCtx);
	
    ISP_SensorGetDefault(IspDev, &pstSnsDft);			
    GAMMAFE_GET_CTX(IspDev, pstGammaFe);
	
    u8WDRMode = pstIspCtx->u8SnsWDRMode;


	//pstGammaFe->bUpGammaFeLut    = HI_FALSE;
	pstGammaFe->u8GammaFeMixCtrl = HI_ISP_GAMMAFE_MIX_CTRL;
	//pstGammaFe->K                = HI_ISP_GAMMAFE_DEFAULT_K;
	//pstGammaFe->S                = HI_ISP_GAMMAFE_DEFAULT_S;
    /* Disable gamma_fe block */
	hi_isp_gamma_fe_enable_write(HI_ISP_GAMMAFE_DEFAULT_STATUS);
	hi_isp_gamma_fe_bitw_in_write(HI_ISP_GAMMAFE_BITW_IN);
	hi_isp_gamma_fe_bitw_out_write(HI_ISP_GAMMAFE_BITW_OUT);
	hi_isp_gamma_fe_mix_ctrl_write(pstGammaFe->u8GammaFeMixCtrl);

	//hi_ext_system_gammafe_k_write(pstGammaFe->K);
    //hi_ext_system_gammafe_s_write(pstGammaFe->S);
	
    if (pstSnsDft->stGammafe.bValid)
    {    
        hi_isp_gamma_fe_waddr1_write(0);

        for(i=0; i<GAMMA_FE0_LUT_SIZE; i++)
        {
        	pstGammaFe->Gamma_Fe_LUT0[i] = pstSnsDft->stGammafe.au16Gammafe0[i];

            hi_isp_gamma_fe_wdata1_write((HI_U32)(pstSnsDft->stGammafe.au16Gammafe0[i]));
        }

		//GenerateGammaFeLut(pstGammaFe);

		hi_isp_gamma_fe_waddr0_write(0);
		
        for(i=0; i<GAMMA_FE1_LUT_SIZE; i++)
        {
        	pstGammaFe->Gamma_Fe_LUT1[i] = pstSnsDft->stGammafe.au16Gammafe1[i];
            hi_isp_gamma_fe_wdata0_write(pstGammaFe->Gamma_Fe_LUT1[i]);
        }
    }
	
	if(IS_LINEAR_MODE(u8WDRMode))
	{
		hi_isp_gamma_fe_enable_write(HI_FALSE);
	}
	else if(IS_BUILT_IN_WDR_MODE(u8WDRMode) || IS_FS_WDR_MODE(u8WDRMode))
	{
		hi_isp_gamma_fe_enable_write(HI_TRUE);
	}
	else 
	{
		hi_isp_gamma_fe_enable_write(HI_FALSE);
	}

    
    return;
}

static HI_S32 GammaFeReadExtregs(ISP_GAMMAFE_S *pstGammaFe)
{
#if 0
	if (pstGammaFe->K != hi_ext_system_gammafe_k_read())
	{
		pstGammaFe->bUpGammaFeLut = HI_TRUE;
		pstGammaFe->K = hi_ext_system_gammafe_k_read();
	}

	if (pstGammaFe->S != hi_ext_system_gammafe_s_read())
	{
		pstGammaFe->bUpGammaFeLut = HI_TRUE;
		pstGammaFe->S = hi_ext_system_gammafe_s_read();
	}
#endif
    return 0;
}

HI_S32 ISP_GammaFeInit(ISP_DEV IspDev)
{
    GammaFeRegsDefault();
    GammaFeExtRegsDefault();
    GammaFeRegsInitialize(IspDev);
    GammaFeExtRegsInitialize(IspDev);

    return HI_SUCCESS;
}

#if 0
static HI_U16  GAMMA_FELut1[GAMMA_FE1_LUT_SIZE] = {
                   0    ,115    ,392    ,587    ,782    ,977    ,1172   ,1367   ,1562   ,1757   ,1952   ,2147   ,2342,
                2537	,2732	,2927	,3122	,3317	,3512	,3707	,3902	,4097	,4292	,4487	,4682	,4877,	
                5072	,5267	,5462	,5657	,5836	,6000	,6159	,6313	,6464	,6611	,6755	,6896	,7034,	
                7170	,7303	,7434	,7564	,7690	,7815	,7936	,8057	,8174	,8291	,8415	,8524	,8622,	
                8716	,8806	,8894	,8980	,9064	,9146	,9227	,9306	,9385	,9461	,9537	,9612	,9686,	
                9758	,9830	,9901	,9970	,10039	,10108	,10175	,10241	,10307	,10372	,10437	,10500	,10563,	
                10626	,10687	,10748	,10809	,10868	,10928	,10986	,11044	,11102	,11159	,11216	,11271	,11327,	
                11382	,11437	,11490	,11544	,11597	,11650	,11702	,11754	,11805	,11856	,11906	,11956	,12006,	
                12055	,12104	,12153	,12201	,12249	,12296	,12343	,12390	,12436	,12473	,12505	,12537	,12568,	
                12600	,12631	,12662	,12692	,12722	,12753	,12782	,12812	,12841	,12870	,12899	,12927	,12956,	
                12984	,13011	,13039	,13066	,13093	,13120	,13147	,13173	,13200	,13226	,13251	,13277	,13302,	
                13328	,13353	,13377	,13402	,13426	,13451	,13475	,13498	,13522	,13546	,13569	,13592	,13615,	
                13638	,13660	,13683	,13705	,13727	,13749	,13770	,13792	,13813	,13835	,13856	,13877	,13898,	
                14169	,14415	,14638	,14842	,15029	,15199	,15356	,15500	,15633	,15755	,15868	,15973	,16073,	
                16166	,16253	,16334	,16409	,16479	,16546	,16608	,16667	,16722	,16775	,16825	,16896	,16962,	
                17026	,17087	,17146	,17204	,17261	,17318	,17432	,17549	,17670	,17799	,18093	,18432	,18819,	
                19258	,19750	,20293	,20885	,21526	,22211	,22938	,23703	,24505	,25339	,26202	,27092	,28006,	
                28941	,29895	,30865	,31850	,32848	,33857	,34875	,35901	,36934	,37971	,39013	,40061	,41112,	
                42166	,43223	,44281	,45340	,46401	,47462	,48524	,49586	,50649	,51712	,52775	,53838	,54902,	
                55965	,57028	,58092	,59155	,60219	,61282	,62346	,63409	,64475	,65535
			   };
static HI_U16  GAMMA_FELut2[GAMMA_FE1_LUT_SIZE] = {
                0,   109,   392,   587,   782,   977,  1172,  1367,  1562,  1757,  1952,  2147,  2342,  2537,  2732,  2927,
  3122,  3317,  3508,  3679,  3844,  4004,  4159,  4311,  4458,  4603,  4744,  4882,  5017,  5149,  5278,  5404,
  5528,  5656,  5766,  5868,  5967,  6062,  6155,  6246,  6335,  6421,  6507,  6591,  6674,  6754,  6834,  6912,
  6989,  7065,  7140,  7214,  7287,  7358,  7430,  7499,  7568,  7636,  7704,  7770,  7836,  7901,  7965,  8029,
  8092,  8154,  8216,  8276,  8336,  8396,  8455,  8513,  8571,  8628,  8684,  8740,  8796,  8851,  8899,  8940,
  8981,  9021,  9061,  9101,  9140,  9179,  9217,  9255,  9293,  9330,  9367,  9403,  9439,  9475,  9510,  9545,
  9580,  9614,  9648,  9682,  9716,  9748,  9781,  9814,  9846,  9878,  9910,  9941,  9972, 10003, 10034, 10064,
 10094, 10123, 10153, 10182, 10211, 10240, 10268, 10296, 10325, 10352, 10380, 10407, 10434, 10461, 10488, 10514,
 10541, 10567, 10592, 10618, 10643, 10669, 10694, 10718, 10743, 10767, 10792, 10816, 10839, 10863, 10887, 10910,
 10933, 10956, 10979, 11001, 11024, 11046, 11068, 11090, 11112, 11134, 11155, 11176, 11198, 11219, 11239, 11260,
 11281, 11301, 11321, 11341, 11361, 11381, 11401, 11421, 11440, 11694, 11926, 12138, 12333, 12512, 12677, 12830,
 12971, 13103, 13226, 13340, 13448, 13551, 13649, 13741, 13829, 13911, 13990, 14065, 14137, 14206, 14272, 14337,
 14399, 14489, 14575, 14660, 14743, 14825, 14907, 14989, 15071, 15238, 15410, 15589, 15776, 16197, 16665, 17183,
 17752, 18371, 19037, 19749, 20503, 21296, 22123, 22983, 23871, 24784, 25720, 26675, 27648, 28635, 29636, 30647,
 31668, 32697, 33733, 34774, 35820, 36869, 37920, 38973, 40030, 41089, 42149, 43209, 44271, 45333, 46396, 47458,
 48522, 49585, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
 65535
			   };
static HI_U16  GAMMA_FELut3[GAMMA_FE1_LUT_SIZE] = {
                1,   197,   392,   587,   782,   977,  1172,  1367,  1562,  1757,  1941,  2114,  2281,  2443,  2599,  2750,
  2897,  3039,  3178,  3312,  3447,  3568,  3679,  3784,  3886,  3985,  4081,  4175,  4266,  4355,  4443,  4529,
  4613,  4695,  4776,  4856,  4934,  5011,  5087,  5161,  5234,  5306,  5378,  5448,  5518,  5585,  5653,  5719,
  5785,  5849,  5909,  5960,  6011,  6061,  6110,  6158,  6206,  6253,  6300,  6346,  6392,  6437,  6481,  6525,
  6569,  6612,  6654,  6696,  6738,  6779,  6819,  6859,  6899,  6938,  6977,  7015,  7053,  7091,  7128,  7165,
  7201,  7238,  7273,  7309,  7344,  7378,  7413,  7447,  7481,  7514,  7547,  7580,  7612,  7644,  7676,  7708,
  7739,  7770,  7801,  7831,  7862,  7892,  7921,  7951,  7980,  8009,  8038,  8066,  8094,  8122,  8150,  8177,
  8205,  8232,  8259,  8285,  8312,  8338,  8364,  8390,  8415,  8441,  8466,  8491,  8516,  8540,  8565,  8589,
  8613,  8637,  8661,  8684,  8708,  8731,  8754,  8777,  8799,  8822,  8844,  8866,  8888,  8910,  8932,  8953,
  8975,  8996,  9017,  9038,  9059,  9079,  9100,  9120,  9140,  9161,  9180,  9200,  9220,  9240,  9259,  9278,
  9297,  9316,  9335,  9354,  9373,  9391,  9410,  9428,  9446,  9685,  9904, 10107, 10294, 10467, 10628, 10779,
 10920, 11053, 11178, 11296, 11407, 11516, 11621, 11720, 11816, 11908, 11996, 12082, 12165, 12246, 12325, 12402,
 12478, 12588, 12697, 12804, 12911, 13017, 13124, 13231, 13339, 13559, 13785, 14020, 14264, 14803, 15389, 16023,
 16704, 17431, 18199, 19006, 19848, 20722, 21624, 22551, 23500, 24468, 25451, 26449, 27459, 28479, 29507, 30542,
 31583, 32629, 33678, 34731, 35786, 36843, 37900, 38958, 40019, 41081, 42143, 43205, 44268, 45331, 46394, 47458,
 48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
 65535
			   };
 static HI_U16 GAMMA_FELut4[GAMMA_FE1_LUT_SIZE] = {
                1,   197,   392,   586,   776,   959,  1133,  1299,  1458,  1610,  1755,  1897,  2023,  2138,  2247,  2352,
  2453,  2551,  2646,  2738,  2828,  2916,  3001,  3084,  3166,  3246,  3324,  3401,  3476,  3548,  3610,  3670,
  3729,  3787,  3845,  3901,  3956,  4011,  4064,  4117,  4169,  4220,  4270,  4320,  4369,  4417,  4465,  4511,
  4558,  4603,  4648,  4692,  4737,  4780,  4823,  4865,  4907,  4948,  4989,  5029,  5069,  5108,  5147,  5186,
  5224,  5262,  5299,  5336,  5373,  5409,  5445,  5480,  5515,  5550,  5584,  5618,  5652,  5685,  5718,  5751,
  5783,  5816,  5847,  5879,  5910,  5941,  5972,  6002,  6032,  6062,  6092,  6121,  6150,  6179,  6208,  6236,
  6264,  6292,  6320,  6347,  6375,  6402,  6428,  6455,  6481,  6508,  6534,  6559,  6585,  6610,  6635,  6660,
  6685,  6710,  6734,  6758,  6782,  6806,  6830,  6853,  6877,  6900,  6923,  6946,  6968,  6991,  7013,  7036,
  7058,  7079,  7101,  7123,  7144,  7165,  7187,  7208,  7228,  7249,  7270,  7290,  7311,  7331,  7351,  7371,
  7390,  7410,  7430,  7449,  7468,  7488,  7506,  7525,  7544,  7563,  7581,  7600,  7618,  7637,  7655,  7673,
  7690,  7708,  7726,  7744,  7761,  7778,  7796,  7813,  7830,  8055,  8263,  8457,  8638,  8808,  8967,  9117,
  9259,  9394,  9522,  9644,  9761,  9877,  9989, 10097, 10202, 10304, 10403, 10500, 10595, 10688, 10780, 10871,
 10961, 11092, 11223, 11352, 11482, 11612, 11743, 11875, 12008, 12278, 12556, 12842, 13138, 13783, 14472, 15205,
 15979, 16793, 17641, 18522, 19431, 20365, 21320, 22294, 23285, 24288, 25303, 26328, 27360, 28399, 29443, 30491,
 31543, 32598, 33654, 34713, 35773, 36833, 37893, 38953, 40015, 41078, 42141, 43204, 44267, 45330, 46394, 47457,
 48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
 65535
			   };
static HI_U16  GAMMA_FELut5[GAMMA_FE1_LUT_SIZE] = {
                1,   197,   377,   554,   717,   868,  1002,  1121,  1231,  1336,  1436,  1532,  1624,  1712,  1798,  1875,
  1946,  2015,  2082,  2147,  2210,  2272,  2333,  2392,  2450,  2507,  2563,  2617,  2671,  2724,  2775,  2826,
  2876,  2925,  2974,  3021,  3068,  3114,  3160,  3205,  3249,  3292,  3336,  3378,  3420,  3461,  3502,  3542,
  3582,  3621,  3661,  3699,  3737,  3774,  3811,  3848,  3884,  3920,  3956,  3991,  4026,  4060,  4094,  4128,
  4161,  4194,  4227,  4259,  4291,  4323,  4355,  4386,  4417,  4447,  4478,  4508,  4537,  4567,  4596,  4625,
  4654,  4682,  4711,  4739,  4767,  4794,  4822,  4849,  4876,  4902,  4929,  4955,  4981,  5007,  5033,  5058,
  5083,  5108,  5133,  5158,  5182,  5207,  5231,  5255,  5279,  5302,  5326,  5349,  5372,  5395,  5418,  5440,
  5463,  5485,  5507,  5529,  5551,  5573,  5595,  5616,  5637,  5658,  5680,  5700,  5721,  5742,  5762,  5783,
  5803,  5823,  5843,  5863,  5883,  5902,  5922,  5941,  5960,  5979,  5998,  6017,  6036,  6055,  6073,  6092,
  6110,  6128,  6146,  6164,  6182,  6200,  6218,  6236,  6253,  6271,  6288,  6305,  6322,  6339,  6356,  6373,
  6390,  6407,  6423,  6440,  6456,  6472,  6488,  6505,  6521,  6734,  6933,  7120,  7296,  7463,  7621,  7771,
  7915,  8053,  8185,  8313,  8436,  8559,  8679,  8796,  8911,  9023,  9133,  9241,  9348,  9454,  9559,  9662,
  9766,  9918, 10069, 10220, 10372, 10524, 10678, 10832, 10988, 11305, 11629, 11961, 12302, 13039, 13816, 14631,
 15480, 16362, 17273, 18209, 19167, 20144, 21136, 22143, 23160, 24187, 25222, 26263, 27309, 28359, 29412, 30467,
 31525, 32584, 33644, 34705, 35767, 36829, 37890, 38951, 40014, 41077, 42140, 43204, 44267, 45330, 46394, 47457,
 48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
 65535
			   }; 
static  HI_U16 GAMMA_FELut6[GAMMA_FE1_LUT_SIZE] = { 1,   183,   346,   474,   586,   689,   782,   862,   939,  1012,  1081,  1148,  1213,  1276,  1336,  1395,
  1452,  1508,  1563,  1616,  1668,  1719,  1769,  1817,  1865,  1912,  1959,  2004,  2049,  2093,  2136,  2178,
  2220,  2262,  2302,  2342,  2382,  2421,  2459,  2498,  2535,  2572,  2609,  2645,  2681,  2716,  2751,  2786,
  2820,  2854,  2887,  2920,  2953,  2985,  3017,  3049,  3080,  3111,  3142,  3173,  3203,  3233,  3263,  3292,
  3321,  3350,  3379,  3407,  3435,  3463,  3491,  3518,  3545,  3572,  3599,  3625,  3652,  3678,  3704,  3729,
  3755,  3780,  3805,  3830,  3855,  3879,  3904,  3928,  3952,  3976,  3999,  4023,  4046,  4069,  4092,  4115,
  4138,  4160,  4183,  4205,  4227,  4249,  4271,  4292,  4314,  4335,  4356,  4377,  4398,  4419,  4440,  4460,
  4481,  4501,  4521,  4541,  4561,  4581,  4601,  4620,  4640,  4659,  4679,  4698,  4717,  4736,  4755,  4773,
  4792,  4810,  4829,  4847,  4865,  4883,  4901,  4919,  4937,  4955,  4972,  4990,  5007,  5025,  5042,  5059,
  5076,  5093,  5110,  5127,  5144,  5160,  5177,  5193,  5210,  5226,  5242,  5259,  5275,  5291,  5306,  5322,
  5338,  5354,  5369,  5385,  5400,  5416,  5431,  5447,  5462,  5665,  5856,  6038,  6210,  6375,  6533,  6684,
  6831,  6972,  7109,  7242,  7372,  7502,  7631,  7756,  7880,  8002,  8123,  8242,  8361,  8478,  8595,  8712,
  8828,  8999,  9170,  9341,  9513,  9685,  9859, 10034, 10211, 10569, 10933, 11306, 11686, 12501, 13349, 14230,
 15139, 16074, 17031, 18008, 19001, 20008, 21026, 22054, 23089, 24131, 25178, 26228, 27282, 28338, 29396, 30456,
 31516, 32578, 33640, 34702, 35765, 36828, 37889, 38950, 40013, 41077, 42140, 43204, 44267, 45330, 46394, 47457,
 48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
 65535
			   }; 
static  HI_U16 GAMMA_FELut7[GAMMA_FE1_LUT_SIZE] = {
                1,   155,   260,   345,   421,   491,   556,   618,   678,   734,   789,   842,   893,   943,   992,  1039,
  1085,  1130,  1174,  1217,  1260,  1301,  1342,  1382,  1421,  1460,  1498,  1536,  1573,  1610,  1646,  1681,
  1716,  1751,  1785,  1819,  1852,  1885,  1917,  1949,  1981,  2013,  2044,  2075,  2105,  2135,  2165,  2195,
  2224,  2253,  2282,  2310,  2338,  2366,  2394,  2421,  2448,  2475,  2502,  2528,  2555,  2581,  2607,  2632,
  2658,  2683,  2708,  2733,  2757,  2782,  2806,  2830,  2854,  2878,  2901,  2925,  2948,  2971,  2994,  3017,
  3039,  3062,  3084,  3106,  3128,  3150,  3172,  3193,  3215,  3236,  3257,  3278,  3299,  3320,  3341,  3361,
  3382,  3402,  3422,  3442,  3462,  3482,  3501,  3521,  3541,  3560,  3579,  3598,  3617,  3636,  3655,  3674,
  3693,  3711,  3730,  3748,  3766,  3784,  3802,  3820,  3838,  3856,  3874,  3891,  3909,  3926,  3944,  3961,
  3978,  3995,  4012,  4029,  4046,  4063,  4079,  4096,  4113,  4129,  4146,  4162,  4178,  4194,  4210,  4226,
  4242,  4258,  4274,  4290,  4306,  4321,  4337,  4352,  4368,  4383,  4398,  4414,  4429,  4444,  4459,  4474,
  4489,  4504,  4519,  4533,  4548,  4563,  4577,  4592,  4606,  4801,  4986,  5163,  5333,  5496,  5655,  5808,
  5957,  6102,  6244,  6383,  6519,  6657,  6793,  6928,  7061,  7192,  7323,  7453,  7582,  7710,  7839,  7966,
  8094,  8283,  8471,  8661,  8850,  9041,  9233,  9427,  9621, 10015, 10414, 10821, 11234, 12113, 13020, 13952,
 14907, 15882, 16874, 17880, 18898, 19925, 20961, 22002, 23049, 24100, 25154, 26210, 27269, 28328, 29389, 30450,
 31512, 32575, 33638, 34701, 35764, 36827, 37888, 38950, 40013, 41077, 42140, 43204, 44267, 45330, 46394, 47457,
 48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
 65535}; 

static  HI_U16 GAMMA_FELut8[GAMMA_FE1_LUT_SIZE] = {
                1,   105,   175,   237,   293,   346,   396,   444,   489,   533,   576,   618,   658,   698,   736,   774,
       811,   847,   883,   918,   952,   986,  1019,  1052,  1085,  1116,  1148,  1179,  1210,  1240,  1270,  1300,
      1329,  1358,  1386,  1415,  1443,  1470,  1498,  1525,  1552,  1578,  1605,  1631,  1657,  1683,  1708,  1734,
      1759,  1783,  1808,  1832,  1857,  1881,  1905,  1928,  1952,  1975,  1998,  2021,  2044,  2067,  2089,  2112,
      2134,  2156,  2178,  2200,  2221,  2243,  2264,  2285,  2307,  2327,  2348,  2369,  2390,  2410,  2430,  2451,
      2471,  2491,  2510,  2530,  2550,  2569,  2589,  2608,  2627,  2646,  2665,  2684,  2703,  2722,  2740,  2759,
      2777,  2796,  2814,  2832,  2850,  2868,  2886,  2904,  2921,  2939,  2957,  2974,  2992,  3009,  3026,  3043,
      3060,  3077,  3094,  3111,  3128,  3144,  3161,  3178,  3194,  3211,  3227,  3243,  3260,  3276,  3292,  3308,
      3324,  3340,  3356,  3371,  3387,  3403,  3418,  3434,  3449,  3465,  3480,  3495,  3510,  3526,  3541,  3556,
      3571,  3586,  3601,  3616,  3630,  3645,  3660,  3675,  3689,  3704,  3718,  3733,  3747,  3761,  3776,  3790,
      3804,  3818,  3833,  3847,  3861,  3875,  3889,  3903,  3916,  4103,  4283,  4457,  4625,  4789,  4948,  5103,
      5256,  5405,  5552,  5696,  5839,  5983,  6127,  6270,  6411,  6552,  6692,  6831,  6970,  7109,  7247,  7385,
      7523,  7727,  7932,  8137,  8343,  8550,  8757,  8966,  9176,  9600, 10029, 10464, 10905, 11836, 12789, 13762,
     14752, 15756, 16773, 17799, 18834, 19875, 20922, 21973, 23027, 24083, 25141, 26201, 27262, 28323, 29385, 30448,
     31511, 32574, 33637, 34700, 35764, 36827, 37888, 38950, 40013, 41077, 42140, 43204, 44267, 45330, 46394, 47457,
     48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
     65535}; 
//K=16,S=14

static  HI_U16 GAMMA_FELut9[GAMMA_FE1_LUT_SIZE] = {
              1,    68,   118,   163,   205,   244,   282,   318,   353,   388,   421,   454,   485,   517,   547,   577,
       607,   636,   665,   693,   721,   748,   776,   802,   829,   855,   881,   907,   932,   957,   982,  1007,
      1031,  1055,  1079,  1103,  1127,  1150,  1173,  1196,  1219,  1241,  1264,  1286,  1309,  1330,  1352,  1374,
      1395,  1417,  1438,  1459,  1480,  1500,  1521,  1542,  1562,  1582,  1603,  1622,  1642,  1662,  1682,  1702,
      1721,  1740,  1760,  1779,  1798,  1817,  1836,  1854,  1873,  1892,  1910,  1928,  1947,  1965,  1983,  2001,
      2019,  2037,  2054,  2072,  2090,  2107,  2125,  2142,  2159,  2177,  2194,  2211,  2228,  2245,  2262,  2278,
      2295,  2312,  2328,  2345,  2361,  2378,  2394,  2410,  2427,  2443,  2459,  2475,  2491,  2507,  2523,  2538,
      2554,  2570,  2585,  2601,  2616,  2632,  2647,  2663,  2678,  2693,  2708,  2723,  2739,  2754,  2769,  2784,
      2799,  2813,  2828,  2843,  2858,  2872,  2887,  2902,  2916,  2931,  2945,  2960,  2974,  2988,  3003,  3017,
      3031,  3045,  3059,  3073,  3087,  3102,  3115,  3129,  3143,  3157,  3171,  3185,  3199,  3212,  3226,  3240,
      3253,  3267,  3280,  3294,  3307,  3321,  3334,  3348,  3361,  3542,  3718,  3889,  4057,  4220,  4381,  4539,
      4694,  4847,  4999,  5149,  5297,  5448,  5599,  5749,  5899,  6048,  6196,  6344,  6492,  6639,  6787,  6934,
      7082,  7300,  7518,  7737,  7957,  8177,  8398,  8620,  8844,  9293,  9747, 10205, 10667, 11640, 12629, 13633,
     14648, 15674, 16708, 17749, 18796, 19846, 20900, 21956, 23014, 24074, 25135, 26196, 27259, 28321, 29384, 30447,
     31510, 32573, 33637, 34700, 35764, 36827, 37888, 38950, 40013, 41077, 42140, 43204, 44267, 45330, 46394, 47457,
     48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
     65535};
//K=17,S=15

static  HI_U16 GAMMA_FELut10[GAMMA_FE1_LUT_SIZE] = {
               
	   0,	 45,	80,   112,	 143,	172,   201,   229,	 256,	282,   308,   333,	 358,	383,   407,   431,
	 455,	 478,	501,   524,   547,	 569,	591,   613,   635,	 657,	678,   699,   720,	 741,	762,   782,
	 803,	 823,	843,   863,   883,	 903,	922,   942,   961,	 980,	999,  1018,  1037,	1056,  1075,  1093,
	1112,	1130,  1149,  1167,  1185,	1203,  1221,  1239,  1256,	1274,  1292,  1309,  1327,	1344,  1361,  1378,
	1396,	1413,  1430,  1447,  1463,	1480,  1497,  1514,  1530,	1547,  1563,  1579,  1596,	1612,  1628,  1644,
    1661,	1677,  1693,  1708,  1724,	1740,  1756,  1772,  1787,	1803,  1819,  1834,  1850,	1865,  1880,  1896,
	1911,	1926,  1941,  1956,  1971,	1986,  2001,  2016,  2031,	2046,  2061,  2076,  2091,	2105,  2120,  2135,
    2149,	2164,  2178,  2193,  2207,	2222,  2236,  2250,  2265,	2279,  2293,  2307,  2321,	2335,  2350,  2364,
	2378,	2392,  2406,  2420,  2434,	2447,  2461,  2475,  2489,	2503,  2516,  2530,  2544,	2557,  2571,  2584,
	2598,	2611,  2625,  2638,  2652,	2665,  2679,  2692,  2705,	2719,  2732,  2745,  2758,	2772,  2785,  2798,
	2811,	2824,  2837,  2850,  2863,	2876,  2889,  2902,  2915,	3092,  3264,  3434,  3601,	3765,  3927,  4088,
    4246,	4404,  4560,  4714,  4868,	5026,  5183,  5340,  5497,	5653,  5809,  5965,  6120,	6276,  6431,  6587,
	6742,	6972,  7202,  7433,  7665,	7897,  8129,  8363,  8597,	9067,  9541, 10017, 10497, 11503, 12520, 13546,
   14581, 15622, 16668, 17719, 18773, 19829, 20887, 21947, 23008, 24069, 25131, 26194, 27257, 28320, 29383, 30446,
   31510, 32573, 33637, 34700, 35763, 36827, 37888, 38950, 40013, 41077, 42140, 43204, 44267, 45330, 46394, 47457,
   48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
  65535};
 //K=18,S=16

static  HI_U16 GAMMA_FELut11[GAMMA_FE1_LUT_SIZE] = {
					  0,    29,    54,    77,   100,   122,   143,   164,   185,   205,   226,   246,   265,   285,   304,   323,
   342,   361,   379,   398,   416,   434,   452,   470,   488,   506,   524,   541,   559,   576,   593,   610,
   627,   644,   661,   678,   695,   712,   728,   745,   761,   778,   794,   810,   827,   843,   859,   875,
   891,   907,   923,   938,   954,   970,   986,  1001,  1017,  1032,  1048,  1063,  1078,  1094,  1109,  1124,
  1139,  1155,  1170,  1185,  1200,  1215,  1230,  1244,  1259,  1274,  1289,  1304,  1318,  1333,  1348,  1362,
  1377,  1391,  1406,  1420,  1435,  1449,  1463,  1478,  1492,  1506,  1520,  1535,  1549,  1563,  1577,  1591,
  1605,  1619,  1633,  1647,  1661,  1675,  1689,  1703,  1717,  1730,  1744,  1758,  1772,  1785,  1799,  1813,
  1826,  1840,  1853,  1867,  1881,  1894,  1908,  1921,  1935,  1948,  1961,  1975,  1988,  2001,  2015,  2028,
  2041,  2055,  2068,  2081,  2094,  2108,  2121,  2134,  2147,  2160,  2173,  2186,  2199,  2212,  2225,  2238,
  2251,  2264,  2277,  2290,  2303,  2316,  2329,  2342,  2355,  2368,  2380,  2393,  2406,  2419,  2432,  2444,
  2457,  2470,  2482,  2495,  2508,  2521,  2533,  2546,  2559,  2731,  2902,  3070,  3237,  3402,  3566,  3729,
  3891,  4052,  4212,  4372,  4531,  4694,  4857,  5021,  5184,  5346,  5509,  5671,  5834,  5996,  6159,  6321,
  6484,  6724,  6964,  7205,  7446,  7688,  7930,  8173,  8416,  8903,  9393,  9884, 10378, 11409, 12446, 13489,
 14537, 15589, 16644, 17701, 18759, 19819, 20880, 21942, 23004, 24067, 25130, 26193, 27256, 28319, 29383, 30446,
 31510, 32573, 33636, 34700, 35763, 36827, 37888, 38950, 40013, 41077, 42140, 43204, 44267, 45330, 46394, 47457,
 48521, 49584, 50648, 51711, 52775, 53838, 54902, 55965, 57028, 58092, 59155, 60219, 61282, 62346, 63409, 64475,
 65535}; 
//K=10,S=0
static  HI_U16 GAMMA_FELut12[GAMMA_FE1_LUT_SIZE] = {
0,   241,   392,   587,   782,   977,  1172,  1367,  1562,  1757,  1952,  2142,  2314,  2481,  2643,  2801,
  2954,  3102,  3247,  3389,  3526,  3661,  3792,  3908,  4019,  4127,  4232,  4334,  4435,  4533,  4630,  4725,
  4818,  4910,  5000,  5089,  5177,  5263,  5349,  5433,  5516,  5599,  5680,  5761,  5841,  5919,  5997,  6073,
  6150,  6225,  6300,  6374,  6446,  6507,  6569,  6629,  6689,  6748,  6808,  6866,  6924,  6981,  7038,  7095,
  7151,  7207,  7262,  7317,  7371,  7425,  7479,  7532,  7585,  7637,  7689,  7741,  7793,  7844,  7894,  7945,
  7995,  8045,  8094,  8143,  8192,  8241,  8289,  8337,  8385,  8432,  8480,  8527,  8574,  8620,  8666,  8712,
  8758,  8803,  8849,  8893,  8938,  8983,  9027,  9071,  9115,  9159,  9203,  9246,  9289,  9332,  9375,  9417,
  9460,  9502,  9544,  9585,  9627,  9668,  9710,  9751,  9792,  9832,  9873,  9913,  9953,  9993, 10033, 10073,
 10113, 10152, 10191, 10231, 10270, 10308, 10347, 10386, 10424, 10462, 10500, 10538, 10576, 10614, 10651, 10689,
 10726, 10763, 10800, 10837, 10874, 10911, 10947, 10984, 11020, 11056, 11092, 11128, 11164, 11200, 11235, 11271,
 11306, 11342, 11377, 11412, 11447, 11482, 11516, 11551, 11585, 12051, 12499, 12932, 13351, 13757, 14151, 14535,
 14909, 15273, 15630, 15978, 16318, 16661, 16999, 17330, 17655, 17974, 18288, 18596, 18899, 19198, 19492, 19781,
 20066, 20480, 20886, 21284, 21674, 22058, 22435, 22806, 23171, 23884, 24576, 25250, 25906, 27218, 28469, 29668,
 30820, 31931, 33004, 34044, 35052, 36033, 36987, 37918, 38826, 39713, 40581, 41431, 42264, 43080, 43882, 44669,
 45442, 46203, 46951, 47688, 48413, 49127, 49830, 50523, 51208, 51884, 52552, 53211, 53862, 54505, 55140, 55769,
 56390, 57005, 57613, 58215, 58810, 59400, 59984, 60562, 61134, 61702, 62264, 62821, 63374, 63921, 64464, 65003,
 65535}; 
#endif
HI_S32 ISP_GammaFeRun(ISP_DEV IspDev, const HI_VOID *pStatInfo,
    HI_VOID *pRegCfg, HI_S32 s32Rsv)
{
	ISP_GAMMAFE_S *pstGammaFe = HI_NULL;   		
    //HI_U32 K;
		
    
    GAMMAFE_GET_CTX(IspDev, pstGammaFe);
	
    GammaFeReadExtregs(pstGammaFe);

    #if 0

     K = pstGammaFe->K;	

	if (pstGammaFe->bUpGammaFeLut)
	{
		HI_U32 i;
		
		//GenerateGammaFeLut(pstGammaFe);

        switch (K)
        {
            case 8:
                    for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut1[i];
                  }
    	
                   break;
            case 9:
                  for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut2[i];
                  }
                   break;
            case 10:
                   for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut3[i];
                  }
                   break;
            case 11:
                  for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut4[i];
                  }
                   break;
            case 12:
                  for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut5[i];
                  }
                   break;
            case 13:
                  for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut6[i];
                  }
                   break;
            case 14:
                   for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut7[i];
                  }
                   break;
            case 15:
                   for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut8[i];
                  }
                   break;
			case 16:
                   for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut9[i];
                  }
                   break;
			case 17:
                   for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut10[i];
                  }
                   break;
		    case 18:
                   for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut11[i];
                  }
                   break;
		    case 100:
                   for (i = 0;i<GAMMA_FE1_LUT_SIZE;i++)
                   {
                      pstGammaFe->Gamma_Fe_LUT1[i] = GAMMA_FELut12[i];
                  }
                   break;
            }         

		hi_isp_gamma_fe_waddr0_write(0);
		
        for(i=0; i<GAMMA_FE1_LUT_SIZE; i++)
        {
            hi_isp_gamma_fe_wdata0_write(pstGammaFe->Gamma_Fe_LUT1[i]);
        }

		pstGammaFe->bUpGammaFeLut = HI_FALSE;
	}
    #endif
    
    return HI_SUCCESS;
}

HI_S32 ISP_GammaFeCtrl(ISP_DEV IspDev, HI_U32 u32Cmd, HI_VOID *pValue)
{
    HI_U8 u8Mode = *((HI_U8 *)pValue);

    switch (u32Cmd)
    {
        case ISP_WDR_MODE_SET:
            ISP_GammaFeInit(IspDev);
            if (IS_LINEAR_MODE(u8Mode))
            {
                /* Bypass pregamma block */
				hi_isp_gamma_fe_enable_write(HI_FALSE);
            }
            else if (IS_BUILT_IN_WDR_MODE(u8Mode)
					|| IS_FS_WDR_MODE(u8Mode))
            {                    
				hi_isp_gamma_fe_enable_write(HI_TRUE);
            }
            else
            {
                /* unknow u8Mode */
				hi_isp_gamma_fe_enable_write(HI_FALSE);
            }
            break;
        default :
            break;
    }
    
    return HI_SUCCESS;
}

HI_S32 ISP_GammaFeExit(ISP_DEV IspDev)
{
    return HI_SUCCESS;
}

HI_S32 ISP_AlgRegisterGammaFe(ISP_DEV IspDev)
{
    ISP_CTX_S *pstIspCtx = HI_NULL;
    ISP_ALG_NODE_S *pstAlgs = HI_NULL;
    
    ISP_GET_CTX(IspDev, pstIspCtx);

    pstAlgs = ISP_SearchAlg(pstIspCtx->astAlgs);
    ISP_CHECK_POINTER(pstAlgs);

    pstAlgs->enAlgType = ISP_ALG_GAMMAFE;
    pstAlgs->stAlgFunc.pfn_alg_init = ISP_GammaFeInit;
    pstAlgs->stAlgFunc.pfn_alg_run  = ISP_GammaFeRun;
    pstAlgs->stAlgFunc.pfn_alg_ctrl = ISP_GammaFeCtrl;
    pstAlgs->stAlgFunc.pfn_alg_exit = ISP_GammaFeExit;
    pstAlgs->bUsed = HI_TRUE;

    return HI_SUCCESS;
}

#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif /* End of #ifdef __cplusplus */

